<template>
    <div style="width: 50%;">
        <!-- 部门管理 -->
        <div>
            <el-input placeholder="输入部门进行搜索..." v-model="filterText" size="small"
                        prefix-icon="el-icon-search" style="margin-bottom: 12px"></el-input>
            <!-- 树形控件 节点方法为 filter-node-method(用于获取节点) -->
            <el-tree :data="deps" :props="defaultProps" :filter-node-method="filterNode" :expand-on-click-node="false" ref="treeRef">
                <!-- 定义节点操作按钮 -->
                <span slot-scope="{node,data}" style="display: flex;justify-content: space-between;width: 100%">
                    <span>{{node.label}}</span> <!-- 树形控件绑定了defaultProps，此处data.name和node.label相等 -->
                    <span>
                        <el-button type="primary" size="mini" @click="()=>showAddDep(data)" class="depBtn">添加部门</el-button>
                        <el-button type="danger" size="mini" @click="()=>deleteDep(data)" class="depBtn">删除部门</el-button>
                    </span>
                </span>
            </el-tree>
        </div>

        <el-dialog title="添加部门" :visible.sync="dialogVisible" width="30%">
            <div style="margin-bottom:5px;margin-left:8px">
                <el-tag>上级部门</el-tag>
                <span style="margin-left:10px">{{pName}}</span>
            </div>
            <div style="margin-bottom:5px;margin-left:8px">
                <el-tag>部门名称</el-tag>
            </div>
                <el-input v-model="addDep.name" size="mini  " placeholder="输入部门名称..." style="margin-left: 8px"></el-input>
            <span slot="footer" class="dialog-footer">
                <el-button size="small" @click="dislogVisible = false">取 消</el-button>
                <el-button size="small" type="primary" @click="doAddDep">确 定</el-button>
            </span>
        </el-dialog>
    </div>
</template>

<script>
export default {
    name:"DepMana",
    data(){
        return{
            // 搜索关键字
            filterText: '',
            // 所有部门数据
            deps: [],
            // 树形控件显示数据
            defaultProps:{
                children: 'children',
                label: 'name',
            },
            // 弹出框
            dialogVisible: false,
            // 添加部门
            addDep:{
                name: '',
                parentId: -1
            },
            pName: '',
        }
    },
    methods:{
        // 获取所有部门数据
        initDeps(){
            this.getRequest('/system/basic/department/').then(resp => {
                if (resp){
                    this.deps = resp;
                }
            })
        },
        // 拦截节点
        filterText(value,data){
            // 观察者事件获取值时，显示值，否则显示所有
            if (!value) return true;
            return data.name.indexOf(value) !== -1;
        },
        // 添加部门按钮点击事件
        showAddDep(data){
            // 当添加部门弹出框打开时，将节点数据赋值给addDep
            this.pName = data.name;
            this.addDep.parentId = data.id;
            this.dialogVisible = true;
        },
        // 删除部门按钮点击事件
        deleteDep(data){
            if (data.isParent === '1') {
                this.$message.error('该部门下还有子部门，无法删除');
            } else {
                // 提示框
                this.$confirm('此操作将永久删除部门['+data.name+']，是否继续？','提示',{
                confirmButtonText:'确定',
                cancelButtonText:'取消',
                type :'warning'
            }).then(() => {
                this.deleteRequest('/system/basic/department/'+ data.id).then(resp =>{
                    if (resp){
                        // 删除后手动将删除的部门从树形控件中移除，就不用再次更新数据，提高用户体验感
                        this.removeDepFromDeps(null,this.deps,data.id)
                    }
                })
            }).catch(() => {
                this.$message({
                    type: "info",
                    message: "已取消操作"
                })
            })
                }   
            },

        // 增加部门
        // 这里有bug，因为采用的是前端自行把添加的部门数据加进树形控件，但是加进去的只有父id和名字，
        // 所以加完后无法删除和再次在该部门下添加子部门，如果要严谨一点，可以直接init，重新刷新部门。
        doAddDep(data) {
            this.postRequest('/system/basic/department/',this.addDep).then(resp => {
                if (resp){
                    this.addDepToDeps(this.deps,this.addDep);
                    // this.initDeps();
                    this.dialogVisible = false;
                }
            })
        },
        // 手动将添加的部门数据添加进树形控件（有bug0
        addDepToDeps(deps,dep){
            for (let i = 0;i < deps.length; i++){
                // 父部门
                let d = deps[i];
                // 判断当前id是否等于要添加数据的父id
                if (d.id === dep.parentId) {
                    // 在当前部门的子部门中添加信息，添加后重新赋值给当前部门
                    d.children = d.children.concat(dep);
                    // 如果当前部门有子部门，将当前部门的is_parent改为1
                    if (d.children.length > 0){
                        d.isParent = 1;
                    }
                    return;
                } else {
                    // 递归
                    this.addDepToDeps(d.children,dep);
                }
            }
        },
        // 手动将删除的部门数据移除出树形控件
        removeDepFromDeps(p,deps,did){
            for (let i = 0;i < deps.length; i++){
                // 父部门
                let d = deps[i];
                // id一样时，说明就是要删除的id
                if (d.id === did) {
                    // 从当前需要删除的id开始
                    deps.splice(i,1)
                    // 如果当前部门没有子部门，更新deps数据，将is_parent改为0
                    if (d.children.length > 0){
                        d.isParent = 0;
                    }
                    return;
                } else {
                    // 递归
                    this.removeDepFromDeps(d,d.children,did);
                }
            }
        }
    },
    // 观察者事件
    watch:{
        // 当filterText的值有变化时，通过ref去调用filter的方法
        // 在树形控件中有：filterNode做拦截，当text的值和节点匹配时，展开节点
        filterText(val) {
                // 当filterText有值时,会自动去找树形控件中匹配的值
                this.$refs.treeRef.filter(val);
        }
    },
    mounted(){
        this.initDeps();
    }
}
</script>

<style>
.depBtn {
        padding: 2px;
    }
</style>